package com.ccp.dev.workflow.controller;

import com.ccp.dev.core.basic.annotion.Action;
import com.ccp.dev.core.basic.consts.SystemConst;
import com.ccp.dev.core.basic.consts.UrlConstants;
import com.ccp.dev.core.basic.internationalization.SysBaseController;
import com.ccp.dev.core.basic.model.SysAuditModelType;
import com.ccp.dev.core.basic.response.ResultData;
import com.ccp.dev.core.basic.util.ContextUtil;
import com.ccp.dev.core.basic.util.UUIDUtils;
import com.ccp.dev.core.basic.web.query.QueryFilter;
import com.ccp.dev.core.jms.IMessageHandler;
import com.ccp.dev.core.util.*;
import com.ccp.dev.core.util.log.SysAuditThreadLocalHolder;
import com.ccp.dev.form.model.FormField;
import com.ccp.dev.form.service.FormFieldService;
import com.ccp.dev.form.xml.util.MsgUtil;
import com.ccp.dev.form.xml.util.XmlUtil;
import com.ccp.dev.system.model.GlobalType;
import com.ccp.dev.system.model.SysOrg;
import com.ccp.dev.system.model.SysRole;
import com.ccp.dev.system.model.SysUser;
import com.ccp.dev.system.service.*;
import com.ccp.dev.workflow.bpmconst.BpmConst;
import com.ccp.dev.workflow.bpminterface.ISkipCondition;
import com.ccp.dev.workflow.bpmutil.ServiceUtil;
import com.ccp.dev.workflow.model.*;
import com.ccp.dev.workflow.model.BpmDefAuthorizeType.BPMDEFAUTHORIZE_RIGHT_TYPE;
import com.ccp.dev.workflow.model.bpm.BpmFormResult;
import com.ccp.dev.workflow.service.*;
import com.ccp.dev.workflow.service.bpm.BpmNodeUserCalculationSelector;
import com.ccp.dev.workflow.service.bpm.IBpmNodeUserCalculation;
import com.ccp.dev.workflow.service.bpm.thread.MessageUtil;
import com.ccp.dev.workflow.xml.FileXmlUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import net.sf.json.JSONArray;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.ui.common.service.exception.BadRequestException;
import org.flowable.ui.common.service.exception.InternalServerErrorException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * ClassDescribe:流程定义模型控制器
 * @author :jiayueqiao
 * Date: 2019-05-15
 * Since:1
 * To change this template use File | Settings | File Templates.
 */
@Controller
@RequestMapping(UrlConstants.PROJECT_ROOT + UrlConstants.PROJECT_MODULE_WORKFLOW + "/actDefModel")
@Action(ownermodel = SysAuditModelType.PROCESS_MANAGEMENT)
public class ActDefModelController extends SysBaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(ActDefModelController.class);

    @Resource
    private ActDefModelService actDefModelService;
    @Resource
    private ObjectMapper objectMapper;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private BpmNodeSetService bpmNodeSetService;
    @Resource
    private BpmUserConditionService bpmUserConditionService;
    @Resource
    private SysOrgService sysOrgService;
    @Resource
    private SysRoleService sysRoleService;
    @Resource
    private SysUserService sysUserService;
    @Resource
    private BpmService bpmService;
    @Resource
    private BpmNodeScriptService bpmNodeScriptService;
    @Resource
    private BpmNodeButtonService bpmNodeButtonService;
    @Resource
    private BpmNodeRuleService bpmNodeRuleService;
    @Resource
    private GlobalTypeService globalTypeService;
    @Resource
    private BpmFlowUserHistoryService bpmFlowUserHistoryService;
    @Resource
    private BpmDefAuthorizeService bpmDefAuthorizeService;
    @Resource
    private FormFieldService formFieldService;
    @Resource
    private BpmNodeUserService bpmNodeUserService;
    @Resource
    private BpmDefVarService bpmDefVarService;
    @Resource
    private BpmNodeUserCalculationSelector bpmNodeUserCalculationSelector;
    @Resource
    private ReferActDefModelService referActDefModelService;
    @Resource
    private ProcessRunService processRunService;
    @Resource
    private TaskReminderService taskReminderService;



    /**
     * 流程定义管理页面
     * @return 跳转路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+UrlConstants.MODULE_FUNCTION_LIST)
    @Action(description = "查看流程定义管理页面",detail="查看流程定义管理页面")
    public String viewList() {
        return getAutoView();
    }

    /**
     * 流程定义管理设置页面
     * @param request request
     * @param model 视图模型
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/commonSetting")
    @Action(description = "查看流程定义管理设置页面",detail="查看流程定义管理设置页面")
    public String viewCommonSetting(HttpServletRequest request,Model model) {
        String modelId = RequestUtil.getString(request,"modelId");
        String parentProcDefId = RequestUtil.getString(request, "parentProcDefId");
        model.addAttribute("modelId",modelId).addAttribute("parentProcDefId",parentProcDefId);

        //主版本modelId，跳转至历史版本跳转时启用
        String modelIdForReturn = RequestUtil.getString(request,"modelIdForReturn");
        if(StringUtil.isNotEmpty(modelIdForReturn)) {
            model.addAttribute("modelIdForReturn", modelIdForReturn);
        }
        //是否跳转至历史模块,历史版本跳转回主版本时启用
        Boolean isHistory = RequestUtil.getBoolean(request,"isHistory",false);
        if(isHistory) {
            model.addAttribute("isHistory", isHistory);
        }

        return getAutoView();
    }

    /**
     * 流程定义设置明细页面
     * @return 跳转路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/detail")
    @Action(description = "查看流程定义管理明细页面",detail="查看流程定义管理明细页面")
    public String viewDetail(HttpServletRequest request,Model model) {
        String modelId = RequestUtil.getString(request,"modelId");
        model.addAttribute("modelId",modelId);
        return getAutoView();
    }

    /**
     * 跳转流程选择器页面
     * @return 跳转路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/selector")
    @Action(description = "查看流程选择器页面",detail="查看流程选择器页面")
    public String viewFlowSelector() {
        return "workflow/actDefModel/selector";
    }

    /**
     * 跳转到分类设置界面
     * @param model mvcModel
     * @param selectedIds 选项id
     * @return 返回路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/categorySet")
    @Action(description = "操作流程定义管理设置分类页面",detail = "操作流程定义管理设置分类页面")
    public String viewCategorySet(Model model, @RequestParam String selectedIds) {
        model.addAttribute("selectedIds", selectedIds);
        return "workflow/actDefModel/categorySet";
    }

    /**
     * 流程选择器数据
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/flowSelector")
    @ResponseBody
    @Action(description = "流程选择器获取流程定义列表数据",detail="流程选择器获取流程定义列表数据<#if fl>成功<#else>失败</#if>")
    public ResultData flowSelector(HttpServletRequest request) {
        QueryFilter queryFilter = new QueryFilter(request);
        String typeId = RequestUtil.getString(request, "typeId");
        if(StringUtil.isNotEmpty(typeId)){
            GlobalType globalType = globalTypeService.getOneById(typeId);
            if(globalType != null){
                queryFilter.addFilter("typeId", typeId);
                queryFilter.addFilter("nodePath", globalType.getNodePath());
            }
        }
        try{
            List<ActDefModel> list = actDefModelService.queryAuthorizedList(queryFilter);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("operation.success",queryFilter.getPageBean().getTotalCount(),list);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return getResultDataError("operation.failure");
        }
    }

    /**
     * 流程分类树选择器 弹窗
     * @return 跳转路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/treeList")
    @Action(description = "操作选择流程分类页面",detail="操作选择流程分类页面")
    public String viewTreeList() {
        return getAutoView();
    }

    /**
     * 流程定义设置其他参数页面
     * @return String
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/otherParam")
    @Action(description = "查看流程定义管理其他参数页面",detail="查看流程定义管理其他参数页面")
    public String viewOtherParam(HttpServletRequest request,Model model) {
        String modelId = RequestUtil.getString(request,"modelId");
        String parentProcDefId = RequestUtil.getString(request,"parentProcDefId");
        model.addAttribute("modelId",modelId);
        model.addAttribute("parentProcDefId",parentProcDefId);
        //节点跳过类型map
        Map<String, ISkipCondition> skipMap = ServiceUtil.getSkipConditionMap();
        model.addAttribute("skipMap", skipMap);
        //消息处理类型map
        Map<String, IMessageHandler> handlersMap = ServiceUtil.getHandlerMap();
        model.addAttribute("handlersMap",handlersMap);
        return getAutoView();
    }

    /**
     * 跳转历史接口
     * @param request request
     * @param model model
     * @return  历史模块跳转路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/history")
    @Action(description = "查看流程定义管理历史页面",detail="查看流程定义管理历史页面")
    public String viewHistory(HttpServletRequest request,Model model){
        String modelId = RequestUtil.getString(request,"modelId");
        String modelIdForReturn = RequestUtil.getString(request,"modelIdForReturn");
        model.addAttribute("modelId",modelId);
        if(StringUtil.isNotEmpty(modelIdForReturn)){
            model.addAttribute("modelIdForReturn",modelIdForReturn);
        }
        return getAutoView();
    }

    /**
     * 指定执行人页面
     * @param request http请求
     * @param model 模型容器
     * @return 跳转路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX + "/flowUserHistory")
    @Action(description = "操作指定执行人页面",detail="流程启动页面，单击指定执行人按钮，弹出的指定执行人操作页面，包含节点指定执行人的历史数据<#if fl>成功<#else>失败</#if>")
    public String viewFlowUserHistory(HttpServletRequest request, Model model) {
        String procDefId = RequestUtil.getString(request, "procDefId");
        String dataPrivacyLevel = RequestUtil.getString(request, "dataPrivacyLevel");
        try{
            ActDefModel actDefModel = actDefModelService.getByProcDefId(procDefId);
            List<FlowNodeInfo> flowNodeList = NodeCache.getFirstNodeList(actDefModel.getProcDefId());

            String userId = ContextUtil.getCurrentUserId();
            List<BpmFlowUserHistory> allHistory = bpmFlowUserHistoryService.queryAllHistoryByParams(procDefId, userId);

            // 将json格式转换成map对象
            List<Map<String,Object>> historyList = new ArrayList<>();
            for (BpmFlowUserHistory bpmFlowUserHistory : allHistory) {
                String userHistoryStr = bpmFlowUserHistory.getUserHistory();
                JSONArray userHistoryJson = JSONArray.fromObject(userHistoryStr);
                Map<String,Object> map = new HashMap<>(3);
                map.put("id", bpmFlowUserHistory.getId());
                map.put("history", userHistoryJson);
                map.put("historyStr", userHistoryStr);
                historyList.add(map);
            }
            // 获取当前流程定义人员修改历史记录
            model.addAttribute("actDefModel",actDefModel)
                    .addAttribute("flowNodeList",flowNodeList)
                    .addAttribute("dataPrivacyLevel",dataPrivacyLevel)
                    .addAttribute("allHistory",historyList);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
        }catch(Exception e){
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("fl", false);
        }
        return getAutoView();
    }

    /**
     * 人员设置界面
     * @param request http请求
     * @return 返回路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/userSet")
    @Action(description = "查看流程定义管理人员设置页面",detail="查看流程定义管理人员设置页面,显示各节点人员设置情况<#if fl>成功<#else>失败</#if>")
    public String viewUserSet(HttpServletRequest request,Model model){
        try{
            //查询所有的节点设置
            String modelId = RequestUtil.getString(request, "modelId");
            String parentProcDefId = RequestUtil.getString(request,"parentProcDefId", "");
            ActDefModel actDefModel = actDefModelService.getOneById(modelId);
            String procDefId = actDefModel.getProcDefId();
            List<BpmNodeSet> setList;
            if (StringUtil.isEmpty(parentProcDefId)) {
                setList = bpmNodeSetService.queryByProcDefId(procDefId);
            } else {
                setList = bpmNodeSetService.queryByProcDefIdAndParentProcDefId(procDefId, parentProcDefId,false);
            }
            List<NodeUserMap> nodeUserMapList = new ArrayList<>();
            // 获取每个节点的人员设置
            for (BpmNodeSet nodeSet : setList) {
                List<BpmUserCondition> bpmUserConditionList = bpmUserConditionService.queryBySetId(nodeSet.getSetId());
                NodeUserMap nodeUserMap = new NodeUserMap();
                nodeUserMap.setSetId(nodeSet.getSetId());
                nodeUserMap.setNodeId(nodeSet.getNodeId());
                nodeUserMap.setNodeName(nodeSet.getNodeName());
                nodeUserMap.setBpmUserConditionList(bpmUserConditionList);
                nodeUserMapList.add(nodeUserMap);
            }
            model.addAttribute("nodeUserMapList",nodeUserMapList)
                    .addAttribute("modelId",modelId)
                    .addAttribute("parentProcDefId",parentProcDefId);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
        }catch(Exception e){
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("fl", false);
        }
        return getAutoView();
    }

    /**
     * 快捷人员设置页面
     * @return 返回路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/userSetQuickly")
    @Action(description = "操作流程定义管理-人员设置-快捷人员设置页面",detail = "操作流程定义管理-人员设置-快捷人员设置页面")
    public String viewUserSetQuickly(HttpServletRequest request,Model model) {
        String modelId = RequestUtil.getString(request,"modelId");
        String parentProcDefId = RequestUtil.getString(request,"parentProcDefId");
        model.addAttribute("modelId",modelId);
        model.addAttribute("parentProcDefId",parentProcDefId);
        return getAutoView();
    }

    /**
     * 节点设置页面
     * @return String
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/nodeSet")
    @Action(description = "查看流程定义管理节点设置页面",detail = "查看流程定义管理节点设置页面")
    public String viewNodeSet(HttpServletRequest request,Model model) {
        String modelId = RequestUtil.getString(request, "modelId");
        String parentProcDefId = RequestUtil.getString(request, "parentProcDefId", "");
        ActDefModel actDefModel = actDefModelService.getOneById(modelId);
        List<FlowNodeInfo> flowNodeList = NodeCache.getFirstNodeList(actDefModel.getProcDefId());
        model.addAttribute("modelId",modelId)
                .addAttribute("parentProcDefId",parentProcDefId)
                .addAttribute("flowNodeList",flowNodeList)
                .addAttribute("procDefId",actDefModel.getProcDefId())
                .addAttribute("deployId",actDefModel.getDeployId())
                .addAttribute("defKey",actDefModel.getProcDefKey());
        return getAutoView();
    }

    /**
     * 设置网关跳转规则页面
     * @return String
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/forkCondition")
    @Action(description = "操作流程定义管理-节点设置-网关节点设置分支条件页面",detail = "操作流程定义管理-节点设置-网关节点设置分支条件页面，显示各路径的执行条件<#if fl>成功<#else>失败</#if>")
    public String viewForkCondition(HttpServletRequest request,Model model) {
        try{
            String modelId = RequestUtil.getString(request, "modelId");
            String nodeId = RequestUtil.getString(request, "nodeId");
            Map<String, Object> attributeMap = actDefModelService.getConditionData(modelId,nodeId);
            if(BeanUtils.isNotEmpty(attributeMap)){
                model.addAllAttributes(attributeMap);
            }
            SysAuditThreadLocalHolder.putParamerter("fl", true);
        }catch(Exception ex){
            ex.printStackTrace();
            LOGGER.error("error:" + ex.getMessage());
            SysAuditThreadLocalHolder.putParamerter("fl", false);
        }
        return getAutoView();
    }

    /**
     * 查询流程模型列表
     * @param request 前端请求
     * @return 包含列表和分页信息的封装类
     */
    @RequestMapping(UrlConstants.MODULE_FUNCTION_LIST)
    @Action(description = "查询流程定义管理页面下的流程定义列表分页数据",detail = "查询流程定义管理页面下的流程定义列表分页数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData list(HttpServletRequest request) {
        try {
            QueryFilter queryFilter = new QueryFilter(request, true);
            String userId = ContextUtil.getCurrentUserId();
            queryFilter.put("userId",userId);

            // 增加流程分管授权查询判断
            String isNeedRight = "";
            Map<String, AuthorizeRight> authorizeRightMap = null;
            if (!ContextUtil.isSuperAdmin()) {
                isNeedRight = "yes";
                Map<String, Object> actRightMap = bpmDefAuthorizeService.getActRightsByUserMap(userId,
                        BPMDEFAUTHORIZE_RIGHT_TYPE.MANAGEMENT, true, true);
                // 获取流程分管授权与用户相关的信息集合的流程key
                String actRights = (String) actRightMap.get("authorizeIds");
                queryFilter.addFilter("actRights", actRights);
                // 获得流程分管授权与用户相关的信息集合的流程权限内容
                authorizeRightMap = (Map<String, AuthorizeRight>) actRightMap.get("authorizeRightMap");
            }
            queryFilter.addFilter("isNeedRight", isNeedRight);

            // 查询流程列表
            List<ActDefModel> list = actDefModelService.queryList(queryFilter);

            // 把前面获得流程分管授权的权限内容设置到流程管理列表
            if (authorizeRightMap != null) {
                for (ActDefModel actDefModel : list) {
                    actDefModel.setAuthorizeRight(authorizeRightMap.get(actDefModel.getModelKey()));
                }
            }else {
                // 如果需要所有权限的就直接虚拟要给又出力权限的对象
                AuthorizeRight authorizeRight = new AuthorizeRight();
                authorizeRight.setRightByAuthorizeType("Y", BPMDEFAUTHORIZE_RIGHT_TYPE.MANAGEMENT);
                for (ActDefModel actDefModel : list) {
                    actDefModel.setAuthorizeRight(authorizeRight);
                }
            }
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("operation.success", queryFilter.getPageBean().getTotalCount(), list);
        } catch (Exception e) {
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return getResultDataError("operation.failure",1,e.getMessage());
        }
    }

    /**
     * 修改模型分类
     * @param request http请求
     * @return 结果封装类
     */
    @RequestMapping("/categorySet")
    @Action(description = "修改流程定义模型的流程分类",detail = "修改流程定义模型${selectedIds}的流程分类<#if fl>成功，修改后的分类名称为${typeName}<#else>失败</#if>")
    @ResponseBody
    public Object categorySet(HttpServletRequest request) {
        String selectedIds = RequestUtil.getString(request, "selectedIds");
        SysAuditThreadLocalHolder.putParamerter("selectedIds",selectedIds);
        String categorySelectId = RequestUtil.getString(request, "categorySelect");
        GlobalType type = globalTypeService.getOneById(categorySelectId);
        if (BeanUtils.isEmpty(type)) {
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return getResultDataError("flowType.not.exist");
        }
        try {
            actDefModelService.updateModelType(selectedIds, categorySelectId);
            SysAuditThreadLocalHolder.putParamerter("typeName",type.getTypeName());
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("update.success");
        } catch (Exception e) {
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return getResultDataError("update.failure",1,e.getMessage());
        }
    }

    /**
     * 保存模型
     * @param modelId 模型id
     * @param values 模型数据集合
     * @return 模型返回封装类
     */
    @RequestMapping(value = "/modelJson/save", method = RequestMethod.POST)
    @Action(description = "保存模型")
    @ResponseBody
    public ModelRepresentation saveModel(@RequestParam String modelId,
                                         @RequestBody MultiValueMap<String, String> values) {

        ActDefModel model = actDefModelService.getOneById(modelId);
        String key = values.getFirst("key");
        if(null!=key){
            key = key.replaceAll(" ", "");
        }
        ModelKeyRepresentation modelKeyInfo = actDefModelService.validateModelKey(model, key);
        if (modelKeyInfo.isKeyAlreadyExists()) {
            throw new BadRequestException("Model with provided key already exists " + key);
        }
        try{
            return actDefModelService.updateModel(model, values);
        }catch (Exception e){
            throw new BadRequestException("Process model could not be saved " + model.getId());
        }
    }

    /**
     * 初始化新模型
     * @param values 模型封装对象
     * @return 模型封装对象
     */
    @RequestMapping(value = "/initModel", method = RequestMethod.POST, produces = "application/json")
    @Action(description = "初始化新模型")
    @ResponseBody
    public ModelRepresentation createModel(@RequestParam String modelId, @RequestBody MultiValueMap<String, String> values){
        ModelRepresentation modelRepresentation = new ModelRepresentation();
        //模型Key
        String key = values.getFirst("key");
        if (StringUtils.isNotEmpty(key)) {
            modelRepresentation.setKey(key.replaceAll(" ", ""));
        }

        ActDefModel newModel;
        try {
            newModel = actDefModelService.initModel(modelId, values, modelRepresentation);
        } catch (Exception e) {
            e.printStackTrace();
            throw new InternalServerErrorException("Could not generate BPMN 2.0 model");
        }
        return new ModelRepresentation(newModel);
    }

    /**
     * 检验模型key是否重复
     * @param modelKey 模型key
     * @return ResultData
     */
    @RequestMapping("/validKey")
    @Action(description = "检验模型key是否重复")
    @ResponseBody
    public ResultData validKey(@RequestParam String modelKey) {
        boolean isStartWithNum = modelKey.matches("[0-9]+.*");
        if (isStartWithNum) {
            return getResultDataError("modelKey.can.not.startWith.number");
        }
        ModelKeyRepresentation modelKeyInfo = actDefModelService.validateModelKey(null, modelKey);
        if (modelKeyInfo.isKeyAlreadyExists()) {
            return getResultDataError("modelKey.already.exists");
        }
        return getResultDataSuccess("valid.input");
    }

    /**
     * 初始化模型节点信息
     * @param response response
     */
    @RequestMapping(value = "/modelJson/init", method = RequestMethod.GET, produces = "application/json")
    public void initModelJSON(HttpServletResponse response) {
        ObjectNode modelNode = objectMapper.createObjectNode();
        ObjectNode modelEditorJson = actDefModelService.createModelJson();
        modelNode.put("modelId", UUIDUtils.getUUIDFor32());
        modelNode.put("deployed", false);
        modelNode.put("name", "");
        modelNode.put("key", "");
        modelNode.put("category", "");
        modelNode.set("model", modelEditorJson);
        try {
            response.setHeader("Content-type",MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().print(modelNode);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取模型节点信息
     * @param modelId 模型id
     * @param response response
     */
    @RequestMapping(value = "/modelJson/get", method = RequestMethod.GET, produces = "application/json")
    public void getModelJSON(@RequestParam String modelId,HttpServletResponse response) {
        boolean deployed = false;

        ActDefModel model = actDefModelService.getOneById(modelId);
        String modelKey = model.getModelKey();
        List<Deployment> deploymentList = repositoryService.createDeploymentQuery().deploymentKey(modelKey).list();
        if(!CollectionUtils.isEmpty(deploymentList)){
            deployed = true;
        }
        ObjectNode modelNode = objectMapper.createObjectNode();
        modelNode.put("modelId", model.getId());
        modelNode.put("name", model.getName());
        modelNode.put("key", model.getModelKey());
        modelNode.put("description", model.getDescription());
        modelNode.put("lastUpdated", DateFormatUtil.format(model.getUpdateTime()));
        modelNode.put("created", DateFormatUtil.format(model.getCreateTime()));
        modelNode.put("lastUpdatedBy", model.getUpdateBy());
        modelNode.put("version", model.getVersion());
        modelNode.put("deployed", deployed);
        modelNode.put("category", model.getTypeId());

        if (StringUtils.isNotEmpty(model.getModelEditorJson())) {
            try {
                ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(model.getModelEditorJson());
                editorJsonNode.put("modelType", "model");
                modelNode.set("model", editorJsonNode);
            } catch (Exception e) {
                LOGGER.error("Error reading editor json {}", modelId, e);
                throw new InternalServerErrorException("Error reading editor json " + modelId);
            }

        } else {
            ObjectNode editorJsonNode = objectMapper.createObjectNode();
            editorJsonNode.put("id", "canvas");
            editorJsonNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorJsonNode.put("modelType", "model");
            modelNode.set("model", editorJsonNode);
        }
        try {
            //设置服务器发给浏览器的数据是使用UTF-8编码的
            response.setCharacterEncoding("UTF-8");
            //告诉浏览器，用UTF-8显示返回的数据
            response.setHeader("Content-type",MediaType.APPLICATION_JSON_UTF8_VALUE);
            response.getWriter().print(modelNode);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 部署模型
     * @param modelId 模型id
     * @return ResultData
     */
    @RequestMapping("/publishModel")
    @Action(description = "发布流程定义模型",detail = "发布流程定义模型,模型id为${modelId},操作<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData publishModel(@RequestParam String modelId) {
        SysAuditThreadLocalHolder.putParamerter("modelId",modelId);
        ActDefModel model = actDefModelService.getOneById(modelId);
        if (model == null) {
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("model.not.exist");
        }
        try {
            actDefModelService.deploy(model);
        } catch (Exception e) {
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("model.publish.failure",1,e.getMessage());
        }
        SysAuditThreadLocalHolder.putParamerter("fl",true);
        return getResultDataSuccess("model.publish.success");
    }

    /**
     * 流程定义明细
     * @param modelId 模型id
     * @return 返回结果封装类
     */
    @RequestMapping("/model/detail")
    @Action(description = "获取流程定义明细数据",detail = "获取流程定义明细数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData get(@RequestParam String modelId) {
        ActDefModel model = actDefModelService.getOneById(modelId);
        if(null!=model){
            if(StringUtil.isNotEmpty(model.getTypeId())){
                GlobalType globalType = globalTypeService.getOneById(model.getTypeId());
                if(null!=globalType){
                    model.setTypeName(globalType.getTypeName());
                }
            }
        }else{
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("operation.failure");
        }
        SysAuditThreadLocalHolder.putParamerter("fl",true);
        return getResultDataSuccess("operation.success", model);
    }

    /**
     * 保存流程参数
     * @param actDefModel 模型对象
     * @return 返回值
     */
    @RequestMapping("/saveParam")
    @Action(description = "保存流程定义管理-其他参数设置",detail = "保存模型id为${modelId}的其他参数设置<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData saveParam(ActDefModel actDefModel){
        SysAuditThreadLocalHolder.putParamerter("modelId",actDefModel.getId());
        try{
            if (actDefModel != null && StringUtils.isNotEmpty(actDefModel.getCcMessageType())) {
                String ccMessageType = StringEscapeUtils.unescapeHtml4(actDefModel.getCcMessageType());
                actDefModel.setCcMessageType(ccMessageType);
            }
            actDefModelService.saveParam(actDefModel);
            SysAuditThreadLocalHolder.putParamerter("fl",true);
            return getResultDataSuccess("model.param.save.success");
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("model.param.save.failure");
        }
    }

    /**
     * 快捷人员设置
     * @param request http请求
     * @return 返回结果封装对象
     */
    @RequestMapping("/userSetQuickly")
    @Action(description = "返回快捷人员设置中的人员及角色数据",detail="返回快捷人员设置中的人员及角色数据")
    @ResponseBody
    public ResultData userSetQuickly(HttpServletRequest request){
        String modelId = RequestUtil.getString(request, "modelId");
        ActDefModel actDefModel = actDefModelService.getOneById(modelId);
        String procDefId = actDefModel.getProcDefId();
        String parentProcDefId = RequestUtil.getString(request,"parentProcDefId", "");
        List<BpmNodeSet> setList;
        if (StringUtil.isEmpty(parentProcDefId)) {
            setList = bpmNodeSetService.queryByProcDefId(procDefId);
        } else {
            setList = bpmNodeSetService.queryByProcDefIdAndParentProcDefId(procDefId, parentProcDefId,false);
        }
        Map<String,Object> resultMap = new HashMap<>(6);
        resultMap.put("nodeSetList", setList);
        resultMap.put("actDefModel", actDefModel);
        resultMap.put("modelId", modelId);
        resultMap.put("parentProcDefId", parentProcDefId);

        //获取所有人员
        List<Map<String,Object>> userList = new ArrayList<>();
        List<SysRole> roleList = new ArrayList<>();
        //获取所有的组织
        SysOrg org = sysOrgService.getOrgByUserId(ContextUtil.getCurrentUserId());
        String orgSupId = org.getOrgSupId();
        if(SystemConst.SUPER_ADMIN_ID.equals(ContextUtil.getCurrentUserId())){
            orgSupId = SystemConst.TOP_ORG_ID;
        }
        Map<String,Object> queryMap = new HashMap<>(2);
        queryMap.put("orgId",orgSupId);
        queryMap.put("currentOrg",org);
        List<SysOrg> sysOrgList = sysOrgService.querySysOrgFlat(queryMap);

        for(SysOrg sysorg:sysOrgList){
            QueryFilter queryFilter = new QueryFilter(request,false);
            queryFilter.put("orgId",sysorg.getOrgId());

            //查询组织下的人员
            List<SysUser> templist = sysUserService.list(queryFilter);
            if(null!=templist && templist.size()>0){
                Map<String,Object> tempMap = new HashMap<>(2);
                tempMap.put("orgName",sysorg.getOrgName());
                tempMap.put("userList",templist);
                userList.add(tempMap);
            }

            if(sysorg.getIsTenant()==1){
                Map<String, Object> params = new HashMap<>(1);
                params.put("orgId", sysorg.getOrgId());
                List<SysRole> tempRoles = sysRoleService.queryRolesByOrgId(params);
                if(null!=tempRoles && tempRoles.size()>0){
                    roleList.addAll(tempRoles);
                }
            }
        }
        resultMap.put("userList", userList);
        resultMap.put("roleList", roleList);
        return getResultDataSuccess("operation.success", resultMap);
    }

    /**
     * 给分支网关添加分支条件
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/addCondition")
    @Action(description = "保存分支网关的分支条件",detail = "保存分支网关的分支条件<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData addCondition(HttpServletRequest request){
        try {
            String modelId = RequestUtil.getString(request, "modelId");
            String nodeId = RequestUtil.getString(request, "nodeId");
            String tasks = request.getParameter("tasks");
            String conditions = request.getParameter("conditions");
            conditions = StringEscapeUtils.unescapeHtml4(conditions);
            String[] aryTasks = tasks.split("#split#");
            String canChoicePathNodeId = RequestUtil.getString(request, "canChoicePathNodeId");
            conditions = " " + conditions + " ";
            String[] aryCondition = conditions.split("#split#");
            Map<String, String> map = new HashMap<>(15);

            for (int i = 0; i < aryTasks.length; i++) {
                String condition = aryCondition[i].trim();
                map.put(aryTasks[i], condition);
            }
            bpmService.saveCondition(modelId, nodeId, map, canChoicePathNodeId);
            SysAuditThreadLocalHolder.putParamerter("fl",true);
        } catch (Exception e) {
            LOGGER.error("error:" + e.getMessage());
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return  getResultDataError("setting.condition.save.failure",1,e.getMessage());
        }
        return  getResultDataSuccess("setting.condition.save.success");
    }



    /**
     * 获取某个流程的历史版本
     * @param modelId 流程定义id
     * @return ResultData
     */
    @RequestMapping(UrlConstants.MODULE_FUNCTION_LIST+ "/history")
    @Action(description = "获取某个流程的历史版本列表数据",detail = "获取模型id为${modelId}的历史版本列表数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData listHistory(@RequestParam String modelId){
        try{
            SysAuditThreadLocalHolder.putParamerter("modelId",modelId);
            //根据ID获取流程模型
            ActDefModel actDefModel = actDefModelService.getOneById(modelId);
            //根据ID获取流程历史版本
            Map<String,Object> map = new HashMap<>(3);
            map.put("modelKey",actDefModel.getModelKey());
            map.put("version",actDefModel.getVersion());
            map.put("isMain",ActDefModel.NOT_MAIN);
            List<ActDefModel> list = actDefModelService.selectAllHistoryVersions(map);
            SysAuditThreadLocalHolder.putParamerter("fl",true);
            return getResultDataSuccess("query.success",list);
        }catch(Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("query.failure");
        }
    }

    /**
     * 删除流程定义或某个历史版本
     * @param  request request
     * @return ResultData
     */
    @RequestMapping("/del")
    @Action(description = "删除流程定义",detail="删除流程定义<#if onlyVersion == \"true\">历史版本</#if>，模型id为${aryId},<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData del(HttpServletRequest request){
        SysAuditThreadLocalHolder.putParamerter("fl",false);
        String onlyVersion = request.getParameter("onlyVersion");
        SysAuditThreadLocalHolder.putParamerter("onlyVersion",onlyVersion);
        //是否仅删除该版本
        boolean isOnlyVersion = "true".equals(onlyVersion);
        try {
            String aryId = RequestUtil.getString(request,"modelId");
            SysAuditThreadLocalHolder.putParamerter("aryId",aryId);
            if(StringUtil.isEmpty(aryId)){
                return getResultDataError("model.no.choose");
            } else {
                String[] aryDefId = aryId.split(",");
                actDefModelService.delModelByIdArray(aryDefId,isOnlyVersion);
                SysAuditThreadLocalHolder.putParamerter("fl",true);
                return getResultDataSuccess("delete.success");
            }
        } catch(Exception e) {
            e.printStackTrace();
            //删除流程定义失败
            return getResultDataError("delete.failure",1,e.getMessage());
        }
    }

    /**
     * 节点设置通知方式 弹窗
     * @param request request
     * @param model 视图模型对象
     * @return 跳转路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/informType")
    @Action(description = "操作流程定义管理-节点设置-通知方式设置页面",detail = "操作流程定义管理-节点设置-通知方式设置页面")
    public String informType(HttpServletRequest request,Model model){
        String procDefId = RequestUtil.getString(request,"procDefId");
        String nodeId = RequestUtil.getString(request,"nodeId");
        String parentProcDefId = RequestUtil.getString(request,"parentProcDefId");
        BpmNodeSet  bpmNodeSet = bpmNodeSetService.getByProcDefIdNodeIdOrParentProcDefId(nodeId,procDefId,parentProcDefId);
        Map  handlersMap = ServiceUtil.getHandlerMap();
        model.addAttribute("bpmNodeSet",bpmNodeSet)
                .addAttribute("handlersMap",handlersMap)
                .addAttribute("parentProcDefId",parentProcDefId)
                .addAttribute("procDefId",procDefId)
                .addAttribute("nodeId",nodeId);
        return getAutoView();
    }

    /**
     * 保存节点设置通知方式
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/saveInformType")
    @Action(description = "保存流程定义管理-节点设置-通知方式设置",detail = "保存流程定义管理-节点设置-通知方式设置<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData saveInformType(HttpServletRequest request){
        try{
            String procDefId = RequestUtil.getString(request,"procDefId");
            String nodeId = RequestUtil.getString(request,"nodeId");
            String parentProcDefId = RequestUtil.getString(request,"parentProcDefId");
            String informType = RequestUtil.getString(request,"informType");
            BpmNodeSet bpmNodeSet = bpmNodeSetService.getByProcDefIdNodeIdOrParentProcDefId(nodeId,procDefId,parentProcDefId);
            bpmNodeSet.setInformType(informType);
            bpmNodeSetService.update(bpmNodeSet);
            SysAuditThreadLocalHolder.putParamerter("fl",true);
            return getResultDataSuccess("save.success");
        } catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("save.failure",1,e.getMessage());
        }
    }

    /**
     * 获取所有流程数据
     * @param request request
     * @param model 视图模型对象
     * @return ResultData
     */
    @RequestMapping( "/getFlow")
    @Action(description = "获取流程数据",detail = "获取流程数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData getFlow(HttpServletRequest request,Model model){
        try{
            QueryFilter queryFilter = new QueryFilter(request);
            queryFilter.addFilter("validStatus","1");
            String modelId = (String)queryFilter.get("modelId");
            String typeId  = (String)queryFilter.get("typeId");
            if(StringUtil.isNotEmpty(typeId)){
                GlobalType globalType = globalTypeService.getOneById(typeId);
                if(globalType != null){
                    queryFilter.addFilter("typeId", typeId);
                    queryFilter.addFilter("nodePath", globalType.getNodePath());
                }
            }
            //查询所有的流程
            List<ActDefModel> list = actDefModelService.queryList(queryFilter);
            //查询已保存的流程引用
            if(StringUtil.isNotEmpty(modelId)) {
                List<ReferActDefModel> referList = referActDefModelService.queryByModelId(modelId);
                model.addAttribute("modelId",modelId)
                        .addAttribute("referList",referList);
            }else{
                model.addAttribute("actDefModelList",list);
            }
            SysAuditThreadLocalHolder.putParamerter("fl",true);
            return getResultDataSuccess("query.success",list);
        }catch(Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("query.failure");
        }
    }

    /**
     * 获取数据库中的流程定义引用
     * @param request request
     * @return list
     */
    @RequestMapping("/getReferFlow")
    @Action(description = "获取数据库中的流程定义引用数据",detail = "获取数据库中的流程定义引用数据")
    @ResponseBody
    public List<ReferActDefModel> getReferFlow(HttpServletRequest request){
        String modelId = RequestUtil.getString(request,"modelId");
        return referActDefModelService.queryByModelId(modelId);
    }
    /**
     * 保存流程定义引用
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/saveReferFlow")
    @Action(description = "保存流程定义引用",detail = "保存流程定义引用<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData saveReferFlow(HttpServletRequest request){
        String   modelId  = RequestUtil.getString(request,"modelId");
        String[] referArr = RequestUtil.getStringAryByStr(request,"referArr");
        String[] delRefers= RequestUtil.getStringAryByStr(request,"delRefers");
        try {
            referActDefModelService.updateRefers(modelId,delRefers,referArr);
            SysAuditThreadLocalHolder.putParamerter("fl",true);
            return getResultDataSuccess("save.success");
        }catch(Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("save.failure");
        }
    }

    /**
     * 删除数据库中的流程定义引用
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/delReferFlow")
    @Action(description = "删除数据库中的流程定义引用",detail = "删除数据库中的流程定义引用<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData delReferFlow(HttpServletRequest request) {
        String refId = RequestUtil.getString(request, "id");
        try {
            referActDefModelService.delById(refId);
            SysAuditThreadLocalHolder.putParamerter("fl",true);
            return getResultDataSuccess("delete.success");
        } catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("delete.failure",1,e.getMessage());
        }
    }
    /**
     * 是否可以直接启动流程，直接启动流程时不需要表单
     * @param request 前端页面请求
     * @return ResultData
     */
    @RequestMapping("/getCanDirectStart")
    @Action(description = "获取是否可以直接启动流程",detail = "获取是否可以直接启动流程<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData getCanDirectStart(HttpServletRequest request){
        try{
            String modelId = RequestUtil.getString(request,"modelId");
            boolean rtn = actDefModelService.getCanDirectStart(modelId);
            SysAuditThreadLocalHolder.putParamerter("fl",true);
            return getResultDataSuccess("operation.success",rtn);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl",false);
            return getResultDataError("operation.failure",1,e.getMessage());
        }
    }

    /**
     * 流程定义设置节点概要页面
     * @param request request
     * @param model 视图模型
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/nodeSummary")
    @Action(description = "查看流程定义设置节点概要页面",detail = "查看流程定义设置节点概要页面")
    public String viewNodeSummary(HttpServletRequest request,Model model) {
        String modelId = RequestUtil.getString(request,"modelId");
        String parentProcDefId = RequestUtil.getString(request,"parentProcDefId");
        ActDefModel actDefModel = actDefModelService.getOneById(modelId);
        String procDefId = actDefModel.getProcDefId();

        Map<String,Object> map = new HashMap<>(2);
        map.put("procDefId",procDefId);
        map.put("setType",BpmNodeSet.SETTYPE_GLOABLEFORM);
        if(StringUtil.isNotEmpty(parentProcDefId)){
            map.put("parentProcDefId",parentProcDefId);
            map.put("isAll",false);
        }
        List<BpmNodeSet> nodeSetList = bpmNodeSetService.getByDefId(map);
        BpmNodeSet globalNodeSet = bpmNodeSetService.getBySetType(map);
        for (BpmNodeSet nodeSet : nodeSetList) {
            if (nodeSet.getNodeId() == null) {
                nodeSetList.remove(nodeSet);
                break;
            }
        }
        //人员配置
        FlowNodeInfo startFlowNode = NodeCache.getStartNode(procDefId);
        List<FlowNodeInfo> endFlowNodeList = NodeCache.getEndNode(procDefId);

        Map<String, Boolean> startScriptMap = new HashMap<>(15);
        Map<String, Boolean> endScriptMap = new HashMap<>(15);
        Map<String, Boolean> preScriptMap = new HashMap<>(15);
        Map<String, Boolean> afterScriptMap = new HashMap<>(15);

        Map<String, Boolean> assignScriptMap = new HashMap<>(15);
        Map<String, Boolean> nodeRulesMap = new HashMap<>(15);

        Map<String, Boolean> bpmFormMap = new HashMap<>(15);
        Map<String, Boolean> buttonMap = new HashMap<>(15);
        Map<String, Boolean> nodeButtonMap = new HashMap<>(15);
        Map<String, Boolean> taskReminderMap = new HashMap<>(15);
        Map<String, Boolean> mobileSetMap = new HashMap<>(15);
        Map<String, Boolean> nodeUserMap = new HashMap<>(15);
        Map<String, Boolean> formMap = new HashMap<>(15);
        Map<String, Boolean> taskApprovalItemsMap = new HashMap<>(15);
        Map<String, Boolean> globalApprovalMap = new HashMap<>(15);
        //用户设置
        this.getNodeUserMap(nodeSetList,procDefId,nodeUserMap,parentProcDefId);
        //流程事件（脚本）
        this.getNodeScriptMap(nodeSetList, procDefId, startScriptMap,endScriptMap, preScriptMap, afterScriptMap, assignScriptMap);
        //流程节点规则
        this.getNodeRulesMap(nodeSetList, procDefId, nodeRulesMap);
        //表单设置
        this.getNodeSetMap(nodeSetList, bpmFormMap, mobileSetMap);
        //操作按钮
        this.getNodeButtonMap(nodeSetList, procDefId, buttonMap, nodeButtonMap);
        //催办信息
        this.getTaskReminderMap(nodeSetList, procDefId, taskReminderMap);
        //全局
        if (checkForm(globalNodeSet)){
            formMap.put("global", true);
        }
        String deployId=null;
        if(null!=actDefModel){
            deployId=actDefModel.getDeployId();
        }

        //封装返回值
        model.addAttribute("actDefModel",actDefModel)
                .addAttribute("deployId", deployId)
                .addAttribute("modelId", modelId)
                .addAttribute("procDefId",procDefId)
                .addAttribute("nodeSetList", nodeSetList)
                .addAttribute("startScriptMap", startScriptMap)
                .addAttribute("endScriptMap", endScriptMap)
                .addAttribute("preScriptMap", preScriptMap)
                .addAttribute("afterScriptMap", afterScriptMap)
                .addAttribute("assignScriptMap", assignScriptMap)
                .addAttribute("nodeRulesMap", nodeRulesMap)
                .addAttribute("nodeUserMap", nodeUserMap)
                .addAttribute("bpmFormMap", bpmFormMap)
                .addAttribute("formMap", formMap)
                .addAttribute("buttonMap", buttonMap)
                .addAttribute("nodeButtonMap", nodeButtonMap)
                .addAttribute("taskReminderMap", taskReminderMap)
                .addAttribute("taskApprovalItemsMap", taskApprovalItemsMap)
                .addAttribute("globalApprovalMap", globalApprovalMap)
                .addAttribute("mobileSetMap", mobileSetMap)
                .addAttribute("startFlowNode", startFlowNode)
                .addAttribute("endFlowNodeList", endFlowNodeList)
                .addAttribute("parentProcDefId", parentProcDefId);
        return getAutoView();
    }

    /**
     * 用户设置
     * @param nodeSetList 节点列表
     * @param procDefId 流程定义id
     * @param nodeUserMap 节点用户
     * @param parentProcDefId 父定义id
     */
    private void getNodeUserMap(List<BpmNodeSet> nodeSetList, String procDefId, Map<String, Boolean> nodeUserMap, String parentProcDefId) {
        Map<String,Object> map = new HashMap<>(5);
        map.put("procDefId",procDefId);
        map.put("conditionType",BpmUserCondition.CONDITION_TYPE_EXEUSER);
        if (StringUtil.isEmpty(parentProcDefId)) {
            map.put("parentProcDefId",parentProcDefId);
        }
        List<BpmUserCondition> bpmUserConditionList = bpmUserConditionService.queryByProcDefIdOrParentId(map);
        for(BpmNodeSet nodeSet:nodeSetList){
            for(BpmUserCondition bpmUserCondition:bpmUserConditionList){
                if(nodeSet.getNodeId().equals(  bpmUserCondition.getNodeId()    )){
                    nodeUserMap.put( nodeSet.getSetId() ,true );
                }
            }
        }
    }

    /**
     * 流程事件（脚本）
     * @param nodeSetList 节点列表
     * @param procDefId 流程定义id
     * @param startScriptMap 开始脚本
     * @param endScriptMap 结束脚本
     * @param preScriptMap 前置脚本
     * @param afterScriptMap 后置脚本
     * @param assignScriptMap 会签脚本
     */
    private void getNodeScriptMap(List<BpmNodeSet> nodeSetList, String procDefId, Map<String, Boolean> startScriptMap, Map<String, Boolean> endScriptMap, Map<String, Boolean> preScriptMap, Map<String, Boolean> afterScriptMap, Map<String, Boolean> assignScriptMap) {
        List<BpmNodeScript> bpmNodeScriptList = bpmNodeScriptService.queryByProcDefId(procDefId);
        //开始和结束
        for(BpmNodeScript bpmNodeScript:bpmNodeScriptList){
            if (StringUtil.isNotEmpty(bpmNodeScript.getNodeId())) {
                if (bpmNodeScript.getScriptType().intValue() == BpmNodeScript.SCRIPT_TYPE_1.intValue()) {
                    startScriptMap.put(bpmNodeScript.getNodeId(), true);
                } else if (bpmNodeScript.getScriptType().intValue() == BpmNodeScript.SCRIPT_TYPE_2.intValue()){
                    endScriptMap.put(bpmNodeScript.getNodeId(), true);
                }
            }
        }
        //脚本、后置、分配
        for (BpmNodeSet nodeSet : nodeSetList) {
            for (BpmNodeScript bpmNodeScript : bpmNodeScriptList) {
                if (StringUtil.isNotEmpty(bpmNodeScript.getNodeId()) && nodeSet.getNodeId().equals(bpmNodeScript.getNodeId())) {
                    if (bpmNodeScript.getScriptType().intValue() == BpmNodeScript.SCRIPT_TYPE_1.intValue()){
                        preScriptMap.put(nodeSet.getSetId(), true);
                    } else if (bpmNodeScript.getScriptType().intValue() == BpmNodeScript.SCRIPT_TYPE_2.intValue()){
                        afterScriptMap.put(nodeSet.getSetId(), true);
                    }else if (bpmNodeScript.getScriptType().intValue() == BpmNodeScript.SCRIPT_TYPE_4.intValue()){
                        assignScriptMap.put(nodeSet.getSetId(), true);
                    }
                }
            }
        }
    }
    /**
     * 流程节点规则
     * @param nodeSetList 节点列表
     * @param procDefId 流程定义id
     * @param nodeRulesMap 规则map
     */
    private void getNodeRulesMap(List<BpmNodeSet> nodeSetList, String procDefId, Map<String, Boolean> nodeRulesMap) {
        List<BpmNodeRule> nodeRuleList = bpmNodeRuleService.getByProcDefId(procDefId);
        for (BpmNodeSet nodeSet : nodeSetList) {
            for (BpmNodeRule bpmNodeRule : nodeRuleList) {
                if (nodeSet.getNodeId().equals(bpmNodeRule.getNodeId())) {
                    nodeRulesMap.put(nodeSet.getSetId(), true);
                }
            }
        }
    }
    /**
     * 表单设置
     * @param nodeSetList 节点列表
     * @param bpmFormMap 表单map
     * @param mobileSetMap mobileSetMap
     */
    private void getNodeSetMap(List<BpmNodeSet> nodeSetList, Map<String, Boolean> bpmFormMap, Map<String, Boolean> mobileSetMap) {
        for (BpmNodeSet nodeSet : nodeSetList) {
            if (nodeSet.getIsAllowMobile().shortValue() == 1) {
                mobileSetMap.put(nodeSet.getSetId(), true);
            }
            if (checkForm(nodeSet)) {
                bpmFormMap.put(nodeSet.getSetId(), true);
            }
        }
    }
    /**
     * 操作按钮
     * @param nodeSetList 节点列表
     * @param procDefId 流程定义id
     * @param buttonMap 按钮map
     * @param nodeButtonMap 节点按钮map
     */
    private void getNodeButtonMap(List<BpmNodeSet> nodeSetList, String procDefId, Map<String, Boolean> buttonMap, Map<String, Boolean> nodeButtonMap) {
        List<BpmNodeButton> nodeButtonList = bpmNodeButtonService.getByProcDefId(procDefId);
        for (BpmNodeButton bpmNodeButton : nodeButtonList) {
            if(bpmNodeButton.getNodeid()!=null) {
                buttonMap.put(bpmNodeButton.getNodeid(), true);
            }else{
                buttonMap.put("startEvent1", true);
            }
        }
        for (BpmNodeSet nodeSet : nodeSetList) {
            for (BpmNodeButton bpmNodeButton : nodeButtonList) {
                if (nodeSet.getNodeId().equals(bpmNodeButton.getNodeid())) {
                    nodeButtonMap.put(nodeSet.getSetId(), true);
                }
            }
        }
    }
    /**
     * 催办信息
     * @param nodeSetList 节点列表
     * @param procDefId 流程定义id
     * @param taskReminderMap 任务催办map
     */
    private void getTaskReminderMap(List<BpmNodeSet> nodeSetList, String procDefId, Map<String, Boolean> taskReminderMap) {
        List<TaskReminder> taskReminderList = taskReminderService.queryByProcDefId(procDefId);
        for (BpmNodeSet nodeSet : nodeSetList) {
            for (TaskReminder taskReminder : taskReminderList) {
                if (nodeSet.getNodeId().equals(taskReminder.getNodeId())) {
                    taskReminderMap.put(nodeSet.getSetId(), true);
                }
            }
        }
    }

    /**
     * 全局  判断是否设置表单
     * @param bpmNodeSet bpmNodeSet
     * @return boolean
     */
    private boolean checkForm(BpmNodeSet bpmNodeSet) {
        if (BeanUtils.isEmpty(bpmNodeSet)) {
            return false;
        }
        if (bpmNodeSet.getFormType().shortValue() == BpmConst.FORM_TYPE_ONLINE.shortValue()) {
            return StringUtil.isNotEmpty(bpmNodeSet.getFormKey());
        } else if (bpmNodeSet.getFormType().shortValue() == BpmConst.FORM_TYPE_URL.shortValue()) {
            return StringUtil.isNotEmpty(bpmNodeSet.getFormUrl());
        }
        return false;
    }

    /**
     * 人员设置 添加人员弹窗
     * @param request request
     * @param model model对象
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/userSetUpdate")
    @Action(description = "流程定义管理-设置-人员设置添加和修改人员弹窗",detail = "流程定义管理-设置-人员设置添加和修改人员弹窗")
    public String windowUserSetUpdate(HttpServletRequest request,Model model) {

        QueryFilter queryFilter = new QueryFilter(request);
        String modelId = (String) queryFilter.get("modelId");
        String nodeId  = (String) queryFilter.get("nodeId");
        String parentProcDefId  = (String) queryFilter.get("parentProcDefId");
        ActDefModel actDefModel   =   actDefModelService.getOneById(modelId);
        String procDefId    =   actDefModel.getProcDefId();
        String conditionId      = (String) queryFilter.get("conditionId");
        //人员规则类型，默认为流程人员，亦可为抄送人员或消息节点人员
        Integer conditionType = RequestUtil.getInt(request, "conditionType",0);
        queryFilter.put("procDefId",procDefId);
        //获取表单结果
        BpmFormResult bpmFormResult = actDefModelService.getBpmFormResult(procDefId,parentProcDefId);


        if (bpmFormResult.getResult() == 1) {
            getResultDataError("form.result.failure");

        }
        //节点名称
        String nodeName="";
        //是否为多实例任务
        boolean isMultiInstance =  false;
        //获取节点设置名称是否是会签节点
        if(StringUtil.isNotEmpty(nodeId)){
            FlowNodeInfo flowNodeInfo=  NodeCache.getNodeByActNodeId(procDefId,nodeId);
            if(flowNodeInfo!=null){
                nodeName = flowNodeInfo.getNodeName();
                if ( flowNodeInfo.getNodeType().equals(FlowNodeInfo.TYPE_USERTASK)) {
                    isMultiInstance = flowNodeInfo.getIsMultiInstance();
                }
            }
        }
        //用户来自（预存弹窗的文本域内容）
        List<BpmNodeUser> userList = new ArrayList<>();
        // conditionId不为空说明是修改表单规则
        if (StringUtil.isNotEmpty(conditionId)) {
            BpmUserCondition bpmUserCondition = bpmUserConditionService.getOneById(conditionId);
            if (bpmUserCondition != null) {
                String formIdentity = bpmUserCondition.getFormIdentity();
                if (bpmFormResult.getResult() == 0) {
                    String name = bpmFormResult.getTableName();
                    // 表名不相等，则说明 之前设置的规则不适合现在的表
                    if (!name.equals(formIdentity)) {
                        bpmUserCondition.setCondition("");
                    }
                }
                model.addAttribute("bpmUserCondition", bpmUserCondition)
                        .addAttribute("setId",bpmUserCondition.getSetId());
            }
            userList = bpmNodeUserService.getByConditionId(conditionId);
        } else {
            BpmUserCondition bpmUserCondition = new BpmUserCondition();
            Long currentSn = TimeUtil.getCurrentTimeMillis();
            bpmUserCondition.setSn(currentSn);
            bpmUserCondition.setFormIdentity(bpmFormResult.getTableName());
            bpmUserCondition.setConditionType(conditionType);
            model.addAttribute("bpmUserCondition", bpmUserCondition)
                    .addAttribute("setId",bpmUserCondition.getSetId());
        }

        // 流程变量
        List<FormField> flowVars = formFieldService.queryFlowVarByFlowProcDefIdOrParentProcDefId(procDefId,parentProcDefId,true);
        // 用户类型
        Map<String, IBpmNodeUserCalculation> assignUserTypes = bpmNodeUserCalculationSelector.getBpmNodeUserCalculation();
        //获取自定义变量
        List<BpmDefVar> bpmDefVars = bpmDefVarService.queryByModelId(modelId);

        model.addAttribute("nodeName",nodeName)
                .addAttribute("userList",userList)
                .addAttribute("bpmDefVars",bpmDefVars)
                .addAttribute("isMultiInstance",isMultiInstance)
                .addAttribute("modelId",modelId)
                .addAttribute("nodeId",nodeId)
                .addAttribute("parentProcDefId",parentProcDefId)
                .addAttribute("actDefModel",actDefModel)
                .addAttribute("flowVars",flowVars)
                .addAttribute("assignUserTypes",assignUserTypes);
        return getAutoView();
    }

    /**
     * 其他参数 抄送人员设置
     * @param request request
     * @param model 视图model对象
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/otherParamCopier")
    @Action(description = "查看流程定义管理-设置-其他参数-抄送人员设置页面",detail = "查看流程定义管理-设置-其他参数-抄送人员设置页面")
    public String viewOtherParamCopier(HttpServletRequest request, Model model) {
        String modelId = RequestUtil.getString(request, "modelId");
        String parentProcDefId =RequestUtil.getString(request,"parentProcDefId");
        ActDefModel actDefModel = actDefModelService.getOneById(modelId);
        //消息类型
        Map<String, IMessageHandler> handlersMap=ServiceUtil.getHandlerMap();

        model.addAttribute("modelId", modelId)
                .addAttribute("procDefId", actDefModel.getProcDefId())
                .addAttribute("parentProcDefId", parentProcDefId)
                .addAttribute("handlersMap", handlersMap);
        return getAutoView();
    }

    /**
     * 获取抄送人员的设置
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/copierList")
    @Action(description = "获取抄送人员设置数据",detail="获取抄送人员设置数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData otherParamCopier(HttpServletRequest request){
        try{
            String procDefId =RequestUtil.getString(request,"procDefId");
            String parentProcDefId =RequestUtil.getString(request,"parentProcDefId");

            Map<String,Object> map = new  HashMap<>(2);
            map.put("procDefId",procDefId);
            map.put("conditionType",BpmUserCondition.CONDITION_TYPE_COPYUSER);
            if (StringUtil.isNotEmpty(parentProcDefId)) {
                map.put("parentProDefId",parentProcDefId);
            }
            List<BpmUserCondition> copierList = bpmUserConditionService.queryByProcDefIdOrParentId(map);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("query.success",copierList);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return getResultDataError("query.failure");
        }
    }

    /**
     * 流程实例
     * @param request request
     * @param model 视图模型对象
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/instances")
    @Action(description = "查看流程实例管理页面",detail="查看流程实例管理页面")
    public String viewInstances(HttpServletRequest request,Model model) {
        String modelId = RequestUtil.getString(request,"modelId");
        model.addAttribute("modelId",modelId);
        return getAutoView();
    }

    /**
     * 流程实例列表数据
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/instances")
    @Action(description = "查询流程实例数据",detail="查询流程实例数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData instances(HttpServletRequest request) {
        try{
            QueryFilter filter = new QueryFilter(request, true);
            // 过滤掉草稿实例
            filter.addFilter("exceptStatus", 4);
            //过滤掉禁用流程实例的定义
            filter.addFilter("exceptDefStatus", 3);
            List<ProcessRun> list = processRunService.getAll(filter);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("operation.success",filter.getPageBean().getTotalCount(),list);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return getResultDataError("operation.failure",1,e.getMessage());
        }
    }

    /**
     * 清除数据
     * @param modelId 模型id
     * @return ResultData
     */
    @RequestMapping("/cleanData")
    @Action(description = "清除流程数据",detail="清除id为${modelId}的流程数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData cleanData(@RequestParam String modelId){
        SysAuditThreadLocalHolder.putParamerter("modelId", modelId);
        try {
            actDefModelService.cleanData(modelId);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return  getResultDataSuccess("clean.data.success");
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return  getResultDataError("clean.data.failure",1,e.getMessage());
        }
    }

    /**
     * 通过模型Key获取主模型Id
     * @param defKey 模型定义key
     * @return ResultData
     */
    @RequestMapping("/getModelIdByDefKey")
    @Action(description = "通过模型Key获取主模型Id",detail="通过模型Key获取主模型Id<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData getModelIdByDefKey(String defKey){
        try{
            ActDefModel actDefModel = actDefModelService.getMainByDefKey(defKey);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("operation.success",actDefModel);
        }catch (Exception e){
            SysAuditThreadLocalHolder.putParamerter("fl", false);
            return getResultDataError("operation.failure",1,e.getMessage());
        }
    }

    /**
     * 检查流程版本
     * @param request request
     * @return ResultData
     */
    @ResponseBody
    @RequestMapping("/checkVersion")
    @Action(description = "检查流程版本",detail="检查流程版本<#if fl>成功<#else>失败</#if>")
    public ResultData checkVersion(HttpServletRequest request){
        SysAuditThreadLocalHolder.putParamerter("fl", false);
        String modelId = RequestUtil.getString(request, "modelId");
        ActDefModel actDefModel = actDefModelService.getOneById(modelId);
        try {
            if (ActDefModel.STATUS_INST_DISABLED.equals(actDefModel.getStatus())) {
                return getResultDataError("model.instance.is.forbidden");
            }
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("model.version.checked.success",actDefModel.getIsMain());
        } catch (Exception e) {
            return getResultDataError("model.version.checked.failure");
        }

    }


    /**
     * 流程节点选择器
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/nodeSelector")
    @Action(description = "查询流程任务节点数据",detail="查询流程任务节点数据<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData selector(HttpServletRequest request){
        SysAuditThreadLocalHolder.putParamerter("fl", false);
        String modelKey = RequestUtil.getString(request,"modelKey");
        ActDefModel actDefModel = actDefModelService.getMainByDefKey(modelKey);
        if(BeanUtils.isEmpty(actDefModel)){
            return getResultDataError("model.query.failure");
        }
        try{
            //返回流程任务节点
            Map<String,String> nodeMap = actDefModelService.getTaskNodes(actDefModel.getId(),null);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
            return getResultDataSuccess("query.success",nodeMap);
        }catch (Exception e){
            e.printStackTrace();
            return getResultDataSuccess("query.failure");
        }
    }

    /**
     * 导入流程xml页面
     * @return 页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/import")
    @Action(description = "操作流程定义导入窗口页面",detail="操作流程定义导入窗口页面")
    public String viewImport(){
        return getAutoView();
    }

    /**
     * 导入流程xml
     * @param request request
     * @return ResultData
     */
    @RequestMapping("/importXml")
    @Action(description = "导入流程定义信息",detail="导入流程定义信息<#if fl>成功<#else>失败</#if>")
    @ResponseBody
    public ResultData importXml(MultipartHttpServletRequest request) {
        MultipartFile fileLoad = request.getFile("file");
        SysAuditThreadLocalHolder.putParamerter("fl", false);
        String message;
        try{
            //默认上传该文件的租户ID
            String tenantId = ContextUtil.getCurrentUserTenantId();
            String msg =this.importZip(fileLoad,tenantId);
            message = MsgUtil.getMessage();
            if(StringUtil.isEmpty(msg)) {
                SysAuditThreadLocalHolder.putParamerter("fl", true);
                return getResultDataSuccess("operation.success",message);
            }else {
                return getResultDataError(msg,1,message);
            }
        }catch (Exception e){
            e.printStackTrace();
            MsgUtil.clean();
            FileUtil.deleteFile(MsgUtil.getFilePath());
            MsgUtil.cleanFilePath();
            String str = MessageUtil.getMessage();
            if(StringUtil.isNotEmpty(str)){
                return getResultDataError("operation.failure",1,str);
            }else {
                return getResultDataError("operation.failure", 1, e.getMessage());
            }
        }
    }

    /**
     * 导入压缩文件
     *
     * @param fileLoad 加载的文件
     * @param tenantId 租户id
     */
    private String importZip(MultipartFile fileLoad, String tenantId) throws Exception {
        String realFilePath=
                StringUtil.trimSufffix(SysFileService.getBasePath(), File.separator)
                        +File.separator+"attachFiles"
                        +File.separator+"tempUnZip"
                        +File.separator;
        //解压文件
        String fileDir = ZipUtil.unZipFile(fileLoad,realFilePath);
        realFilePath = realFilePath+fileDir+File.separator;
        String xmlStr = FileUtil.readFlowFile(realFilePath+fileDir+".flow.xml");
        if(StringUtil.isEmpty(xmlStr)){
            return "importXml.exts.failure";
        }
        Document doc = Dom4jUtil.loadXml(xmlStr);
        Element root = doc.getRootElement();
        //验证格式是否正确
        String msg = XmlUtil.checkXmlFormatReturnMsgStr(root, "bpm", "actDefModels");
        if(StringUtil.isNotEmpty(msg)){
            return msg;
        }
        actDefModelService.importXml(xmlStr,realFilePath,tenantId);
        //删除临时解压文件目录
        FileUtil.deleteDir(new File(realFilePath));
        return null;
    }

    /**
     * 导出流程页面
     * @param request request
     * @param model 视图model对象
     * @return 视图页面路径
     */
    @RequestMapping(UrlConstants.VIEW_DISPATCH_PREFIX+"/export")
    @Action(description = "操作流程定义导出窗口页面",detail="操作流程定义导出窗口页面")
    public String viewExport(HttpServletRequest request,Model model){
        String ids = RequestUtil.getString(request,"ids");
        model.addAttribute("ids",ids);
        return getAutoView();
    }

    /**
     * 导出流程xml
     * @param request request
     * @param response response
     */
    @RequestMapping("/exportXml")
    @Action(description = "导出流程定义信息",detail="导出流程定义信息，id为${ids},操作<#if fl>成功<#else>失败</#if>")
    public void exportXml(HttpServletRequest request,HttpServletResponse response){
        String[] ids = RequestUtil.getStringAryByStr(request,"ids");
        if(BeanUtils.isEmpty(ids)){
            return ;
        }
        //将需要导出的流程定义的id记录到日志中
        String idStr = RequestUtil.getString(request,"ids");
        SysAuditThreadLocalHolder.putParamerter("ids", idStr);
        Map<String,Boolean> map = new HashMap<>(18);
        //流程定义
        map.put("actDefModel",true);
        //历史版本
        map.put("actDefModelHistory",RequestUtil.getBoolean(request,"actDefModelHistory"));
        //流程节点设置
        map.put("bpmNodeSet",true);
        //流程人员设置
        map.put("bpmNodeUser",RequestUtil.getBoolean(request,"bpmNodeUser"));
        map.put("bpmUserCondition",RequestUtil.getBoolean(request,"bpmUserCondition"));
        map.put("bpmNodeUserUplow",RequestUtil.getBoolean(request,"bpmNodeUserUplow"));
        //流程定义权限
        map.put("bpmDefRights",RequestUtil.getBoolean(request,"bpmDefRights"));
        //常用语设置
        map.put("taskApprovalItems",RequestUtil.getBoolean(request,"taskApprovalItems"));
        //流程跳转规则
        map.put("bpmNodeRule",RequestUtil.getBoolean(request,"bpmNodeRule"));
        //流程事件脚本
        map.put("bpmNodeScript",RequestUtil.getBoolean(request,"bpmNodeScript"));
        //流程操作按钮设置
        map.put("bpmNodeButton",RequestUtil.getBoolean(request,"bpmNodeButton"));
        //流程变量
        map.put("bpmDefVar",RequestUtil.getBoolean(request,"bpmDefVar"));
        //流程节点催办事件设置
        map.put("taskReminder",RequestUtil.getBoolean(request,"taskReminder"));
        //流程会签规则
        map.put("bpmNodeSign",RequestUtil.getBoolean(request,"bpmNodeSign"));
        //流程消息
        map.put("bpmNodeMessage",RequestUtil.getBoolean(request,"bpmNodeMessage"));

        map.put("bpmGangedSet",true);
        //内（外）部子流程
        map.put("subActDefModel",RequestUtil.getBoolean(request,"subActDefModel"));
        //自定义表单和其对应的表
        map.put("formDef",RequestUtil.getBoolean(request,"formDef"));
        map.put("formTable",RequestUtil.getBoolean(request,"formDef"));
        //流程SQL定义
        map.put("bpmDefSql",RequestUtil.getBoolean(request,"bpmDefSql"));
        //流程触发定义
        map.put("bpmTriggerDef",RequestUtil.getBoolean(request,"bpmTriggerDef"));
        //消息模块定义
        map.put("nodeMsgTemplate",RequestUtil.getBoolean(request,"nodeMsgTemplate"));

        try{
            this.exportZip(ids,map,request,response);
            SysAuditThreadLocalHolder.putParamerter("fl", true);
        }catch (Exception e) {
            e.printStackTrace();
            SysAuditThreadLocalHolder.putParamerter("fl",false);
        }
    }

    /**
     * 导出压缩文件
     *
     * @param ids 模型id数组
     * @param map 导出设置map
     * @param request request
     * @param response response
     */
    private void exportZip(String[] ids, Map<String, Boolean> map, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String nowDate = DateFormatUtil.getNowByString("yyyyMMddHHmmss");
        String fileName= "ActDefModel_"+nowDate;

        String zipFileName=fileName+".zip";

        String realFilePath=
                StringUtil.trimSufffix(SysFileService.getBasePath(), File.separator)
                +File.separator+"attachFiles"
                +File.separator+"tempZip"
                +File.separator;
        String filePath = realFilePath + fileName;
        String zipFilePath = realFilePath + zipFileName;

        //导出XML
        String strXml = actDefModelService.exportXml(ids,map,filePath);
        // 写XML
        FileXmlUtil.writeXmlFile(fileName + ".flow.xml", strXml, filePath);
        // 打包
        ZipUtil.zip(filePath, true);
        // 导出
        FileUtil.downLoadFile(request, response, zipFilePath, zipFileName);
        // 删除导出的文件
        FileUtil.deleteFile(zipFilePath);

    }


}